//
//  BEThreadExtension.swift
//  BasicExtensions
//
//  Created by 范晓鑫 on 2022/12/27.
//

import Foundation

extension Thread {
    /// 常驻线程, name 为线程名
    public convenience init(permanent name: String?) {
        self.init {
            let thread = Thread.current
            thread.name = name
            let runloop = RunLoop.current
            runloop.add(NSMachPort(), forMode: .common)
            runloop.run()
        }
    }
    /// 常驻线程，自动调用start
    public class func detachNewThread(permanent name: String?) -> Thread {
        let thread = Thread(permanent: name)
        thread.start()
        return thread
    }
    /// 在子线程上执行操作
    @objc fileprivate func _beExecuteOnThread(_ object: BEThreadExecutionObject) {
        object.result = object.action()
    }
    /// 在子线程上执行操作
    @discardableResult
    private func _beExecute(waitUntilDone: Bool = false, _ action: @escaping () -> Any?) -> Any? {
        let object = BEThreadExecutionObject(action: action)
        self.perform(#selector(self._beExecuteOnThread(_:)), on: self, with: object, waitUntilDone: waitUntilDone)
        return object.result
    }
    /// 同步操作
    public func `sync`(_ action: @escaping () -> Void) {
        self._beExecute(waitUntilDone: true, action)
    }
    /// 同步操作
    public func `sync`<T>(_ action: @escaping () -> T) -> T {
        return self._beExecute(waitUntilDone: true, action) as! T
    }
    /// 异步操作
    public func `async`(_ action: @escaping () -> Void) {
        self._beExecute(waitUntilDone: false, action)
    }
}

fileprivate class BEThreadExecutionObject: NSObject {
    let action: () -> Any?
    var result: Any?
    init(action: @escaping () -> Any?) {
        self.action = action
    }
}
